#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <vector>
#include <functional>
#include <sys/wait.h>
#include "Task.h"

#include "channel.h"

using namespace std;

using work_t = function<void()>;

class ProcessPool
{

public:
    ProcessPool(int n, work_t w)
        : processnum(n), work(w)
    {
    }
    int InitProcessPool()
    {
        for (int i = 0; i < processnum; i++)
        {
            int pipedf[2] = {0};
            int n = pipe(pipedf);
            if (n < 0)
            {
                return 2;
            }
            pid_t id = fork();
            if (id < 0)
            {
                return 3;
            }
            if (id == 0)
            {

                cout << getgid() << ",child close history fd: ";

                for (auto &c : channels)
                {
                    cout << c.wfd() << " ";
                    c.Close();
                }

                std::cout << " over" << std::endl;
                // 子进程
                close(pipedf[1]);
                std::cout << "debug: " << pipedf[0] << std::endl;
                dup2(pipedf[0], 0);
                work();
                exit(0);
            }
            close(pipedf[0]);
            channels.emplace_back(pipedf[1], id);
        }
        return 0;
    }
    // void DebugPrint()
    // {
    //     for (auto &e : channels)
    //     {
    //         cout << e.Name() << endl;
    //     }
    // }

    void DispatchTak()
    {
        int who = 0;
        int sum = 5;
        while (sum--)
        {
            // 1.选择一个任务
            int task = ttm.Selectask();
            // 2.选择一个子进程
            Channel &cur = channels[who++];
            who %= channels.size();

            std::cout << "################################" << endl;
            std::cout << "send" << task << "to" << cur.Name() << "任务还剩" << sum << endl;
            std::cout << "################################" << endl;
            // c.派发任务
            cur.SendTask(task);
            sleep(1);
        }
    }

    void closestack()
    {
        for (auto e : channels)
        {
            e.Close();
            pid_t rid = waitpid(e.ID(), nullptr, 0);
            if (rid > 0)
            {

                cout << "child" << rid << "wiat.... success" << endl;
            }
        }
    }

private:
    std::vector<Channel> channels;
    int processnum;
    work_t work;
};
